package KNNCalculate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Vector;
/**
 * Created by Administrator on 2016/12/3 0003.
 * 此算法用于计算文字的向量模型，存储在HashMap<String, Vector<Double>> dv中
 * 并且如果为库中文字，需进行向量归一化，存储在HashMap<String, Vector<Double>> finalDv中
 */
public class DVM extends featureSelect {
    public static final int len=6;
    public static HashSet<String> features = new HashSet<String>();// 存放最终选择的特征词
    public static Object[] feature_array;
    public HashMap<String, Vector<Double>> dv = new HashMap<String, Vector<Double>>();
    public HashMap<String, Vector<Double>> finalDv = new HashMap<String, Vector<Double>>();
    public double[][] sqrt = new double[num][len];

    public static void initFeatures() {
        ArrayList<String> fea=featureSelect.FS();
        for (int i = 0; i < fea.size(); i++) {
            String res = fea.get(i);
            features.add(res);
        }
        feature_array = features.toArray();
    }

    public void buildDVM(int i,String line,HashMap<String,ArrayList<Short>> wordFreq) {
        HashMap<String, Double> fea_wei = new HashMap<String, Double>();
        String []words=line.split("");
            for (int j = 0; j < words.length; j++) { // 逐个读取文档中的词语
                String word = words[j];
                if (!features.contains(word))
                    continue;
                int tf = 0; // 特征项在本文档中出现的频率
                int Ni = 0; // 出现特征项的文档数目
                int N = row; // 全部文档数目
                ArrayList<Short> al =wordFreq.get(word);
                tf = al.get(i);
                for (int k = 0; k < N; k++) {
                    if (al.get(k) > 0)
                        Ni++;
                }
                // System.out.println("word="+word+"\tfilenmae="+filename+"\ttf="+tf+"\tNi="+Ni);
                double weight = -1.0 * tf
                        * Math.log(1.0 * Ni / N + Double.MIN_VALUE);
                fea_wei.put(word, weight);
            }
            Vector<Double> v = new Vector<Double>(len);
            for (int x = 0; x < len; x++) v.add(0.0);
            for (int n = 0; n < feature_array.length; n++) {
                String feat = feature_array[n].toString();
                double w = 0.0;
                if (fea_wei.containsKey(feat))
                    w = fea_wei.get(feat);
                v.set(n, w);
                sqrt[i][n] += Math.pow(w, 2);
            }
            dv.put(String.valueOf(i), v);
    }


    //文档向量归一化
    public void unionVector() {
        Iterator<Entry<String, Vector<Double>>> iter = dv.entrySet().iterator();
        int s=0;
        while (iter.hasNext()) {
            Entry<String, Vector<Double>> entry = iter.next();
            String fname = entry.getKey();
            Vector<Double> v = entry.getValue();
            Iterator<Double> it = v.iterator();
            int index = 0;
            Vector<Double> res = new Vector<Double>(len);
            for (int x = 0; x < len; x++) res.add(0.0);
            while (it.hasNext()) {
                    double d =it.next();
                    d =Math.pow(Math.atan(d),2)/Math.PI;//归一化公式：y=arctan(x)*2/PI
                    //归一化
                    if(d>0)res.set(index,d);
                    index++;
            }
            finalDv.put(String.valueOf(s),res);s++;
        }
    }

    public void Build() {
        this.initFeatures();
        for (int i=0;i<anList.row;i++){
            if(i<AnswerListNo.length) this.buildDVM(i,AnswerListNo[i],anList.wordfreq);
            else this.buildDVM(i,AnswerListYes[i-AnswerListNo.length],anList.wordfreq);
        }
        this.unionVector();
    }
}




